Computer software is ubiquitous. It is used to operate our cars, our cellular phones, our televisions, and of course, our personal computers. In 2007, the United States Environmental Protection Agency estimated that Americans collectively own three billion electronic devices. Many of these devices run software to provide us with capabilities upon which we have become increasingly dependent.
Our increasing dependence on such electronic devices and the increasing prevalence of such devices creates vulnerabilities to our activities and lifestyles from attacks on these devices. Although software gives electronic devices many of the capabilities that we want and need, software also is part of the vulnerability of many of these devices. The ramifications to individuals, companies, and society are grave if cell phones, vehicles, televisions, and other electronic devices fail to work properly or not at all. Such failures can affect our ability to get to work, pay our bills, or buy our food to cite just a few examples of the adverse consequences that could result from software exploitation of electronic devices. As computer software increases society's standard of living with respect to communication and convenience, this benefit alone warrants improved software security. However, a much greater need exists for software security.
Besides our personal lives, our national security depends on computer software. Power grids, financial systems, airlines, and virtually every defense system use software. These systems are vulnerable to attack at many levels, including their software. The damage from a successful attack on any of these systems could be incalculable. If a software vulnerability led to a crash of the stock market or erasure and destruction of bank accounts and financial records, the financial system could be thrown into chaos. If our adversaries could control our defense systems, our national defense would be jeopardized. These examples illustrate the grave risks arising from software vulnerability and exploitation. There are many other scenarios where an attack on computer software would result in severe loss for the country because software security crosses all physical domains of land, sea, air, and space.
Software security experts such as Gary McGraw attribute the growth and evolution of software vulnerability to connectivity, extensibility and complexity. These characteristics often result in design and implementation errors that are vulnerable to attack. In turn, these vulnerabilities result in the development of malicious code (malware) such as worms, viruses, backdoors and rootkits designed to exploit these vulnerabilities. The number of vulnerabilities reported each year by the Computer Emergency Response Team has increased from less than 300 in 1995 to more than 8,000 in 2006 and more than 7,000 in 2007.
The increased connectivity of computers and networks gives would-be attackers the ability to attack systems independent of their geographical location. For example, the Internet provides connectivity to banks and airline systems. Power grids are interconnected by supervisory control and data acquisition (SCADA) systems. Businesses use online web services, such as email, instant messaging, and advertising. Increased system connectivity increases exposure, and thus attack surface.
Connectivity exists in both virtual and physical domains. A virtually closed system (local connectivity only) is not secure because access to the systems' physical hardware could result in a compromise. Furthermore, an attacker could gain access to a closed system by blackmailing or impersonating a legitimate user of the system.
Extensibility is another major factor to consider when securing computer software. In computer software, extensibility is a design principle that incorporates the ability for software to grow. Software is developed to fill a need, but that need changes constantly. Major operating systems such as WINDOWS®, LINUX®, and BSD®, were designed to be updated. Newer versions of operating systems are constantly being released and each release adds new vulnerabilities. Even with cryptographic signing, it is not always possible for a system to determine if an update or extension is malicious.
Complexity is a third major factor that affects software security. Software complexity is often measured in lines of code. The more lines of code in a program, the more potential vulnerabilities exist. Microsoft WINDOWS® Vista alone consists of fifty million lines of code. Other WINDOWS® operating systems range in complexity from WINDOWS® 3.1 with around four million lines of code to WINDOWS® XP with forty million lines of code. Even if every vulnerability in an operating system was discovered and removed, applications and device drivers that run on those operating systems could contain errors that make the overall computer system and its software vulnerable to attack.
As a result of the vulnerabilities inherent in connectivity, extensibility, and complexity, attackers can gain access to, and maintain a presence within, computer systems using a wide variety of software exploits, backdoors, and rootkits. Although each of these techniques provides separate attack capabilities, almost all of these techniques execute malicious code. Malicious code also may be used as a means to thwart security mechanisms and exfiltrate confidential information from a system. A common thread of each of these schemes is that an attacker compromises a computer system by executing code within that system.
Connectivity, extensibility, and complexity also make it difficult to design and implement secure software. Consequently, detection and protection technologies have been developed. However, these technologies are ineffective in preventing all vulnerabilities within a software environment. As long as software vulnerabilities can be exploited, as they currently can, there will be a need for improved software security.
Operating systems currently in use are designed for general purpose computing. For example, WINDOWS®, LINUX®, BSD®, SUNOS®, and UNIX® operating systems help fulfill a variety of capabilities by allowing users to execute arbitrary code. Although most operating systems provide some security (separate user and kernel address space along with object access control, privileges, and the like), common attack techniques such as exploits, backdoors and rootkits may execute in the user-space, at the least privileged level. This can occur because an attacker can execute arbitrary code, as well as a user. Furthermore, CPUs unremittingly execute code without knowing anything about its semantics. To provide better security within traditional operating systems, it is essential to control and limit the specific code executed on those operating systems.
One approach has been the use of software emulation. FIG. 6 illustrates a known emulation model 600 that includes a Guest OS Memory 601 and a Host OS Memory 602. The Guest OS Memory 601 includes Guest OS Instructions 603. The Host OS Memory 602 includes registers for Guest OS Instructions 604 and for Translated Guest OS Instructions 605. The Guest OS Memory 601 is thereby emulated by the Host OS Memory 602. At step 610, the Host OS Memory 602 copies Guest OS instructions 603 from the Guest OS Memory 601 into the Host OS Memory 604. At step 620, the Guest OS instructions 604 in the Host OS Memory 602 are translated (or interpreted) into Translated Guest OS Instructions 605 that run on the Host OS Memory 602 as Host OS instructions. When these Translated Guest OS instructions execute in the Host OS Memory 602, the state of the Guest OS Memory 601 and registers are modified at step 630 such that it appears as if the original Guest OS instructions 603 had been executed in the Guest OS Memory 601.
This emulation process provides a sandbox that ensures that the Guest OS instructions 603 read and write in the Guest OS Memory 601, exclusively. The Host OS Memory 602 cannot be accessed by the Guest OS instructions 603 that reside in the Guest OS Memory 601. Thus, any attacks on the Guest OS memory 601, even if successful, cannot reach or otherwise affect the Host OS Memory 602 where the copied Guest OS Instructions 604 are translated and executed. In addition, the translated Host OS Instructions, i.e., the Translated Guest OS Instructions 605, cannot read or write the Host OS memory 602. As a result, the Translated Guest OS Instructions 605 are never self-reading. A would-be attacker is confined in the Guest OS Memory sandbox 601, unable to access or otherwise manipulate the Guest OS Instructions 604 that are emulated, translated, and executed by the Host OS Memory 602. In this way, would-be attackers are prevented from introducing malicious code in the Host OS Memory 602.
Although such emulation schemes can reduce software vulnerabilities to a restricted environment, they do not protect against reverse code engineering (RCE) of the software within that environment. They also do not protect against software vulnerabilities such as buffer overflows, index array out of bound errors, race conditions, integer overflows, and other types of memory corruption vulnerabilities. Thus, such schemes still do not provide adequate protection for computer devices and software against attempts to bypass a security policy.